package 多线程;



/**
 * @ClassName : Demo01
 * @Author : LV88VL
 * @Date: 2021/3/6 10:14
 * @Description : 多线程
 * 有两种方法来创建一个新的执行线程，在实际开发中，主要使用第二种方法（接口的好处）
 *
 * 一是声明一个类是一类Thread。
 * 这类应重写类Thread的run方法。
 * 通过对象的start方法开启线程
 *
 *
 * 面试题：线程调用run方法和start方法的区别：
 * 调用run方法不开启线程，仅仅是对象调用方法
 * 用start方法开启线程，并让jvm调用run方法在开启的线程中执行
 *
 *
 * 二是实现Runable接口(更加符合面向对象，适用于子类方法中需要线程，而父类方法不管)
 * 重写run方法，
 * 创建Thread类对象，
 * 将Runnable接口的子类对象作为参数传递给Thread类的构造函数，
 * 通过调用Thread类的start方法开启线程
 *
 *
 * 在实际开发中，主要使用第二种方法（接口的好处）
 * 实现Runnable接口的方式更加符合面向对象，线程分为两个部分，一部分是线程对象，一部分是线程任务
 * 继承Thread类，线程对象和任务耦合在一起，一旦创建Thread的子类对象，既有线程对象，又有线程任务
 * 实现Runnable接口，将线程任务单独分离出来封装成对象，类型就是Runnable接口类型
 *
 */
//第一种方法实现
class DemoText1 extends Thread {
    private String name;
    DemoText1(String name)
    {
        this.name = name;
    }
    public void run()
    {
        for (int x = 0; x < 200; x++) {
            System.out.println("name="+name+"......"+x);
        }
    }
}
//第二种方法实现
class DemoText2 implements Runnable
{
    private int i=10;
    private Object obj=new Object();
    @Override
    public void run() {
        while (true){
            /**synchronized (obj){
                if (i>0) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) { }
                    System.out.println(Thread.currentThread().getName()+"........"+i--);
                }
            }*/
            this.test();
        }
    }
    public synchronized void test(){
        if (i>0) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) { }
            System.out.println(Thread.currentThread().getName()+"........"+i--);
        }
    }
}
class TreadDemo
{
    public static void main(String[] args)
    {
        /**创建了两个线程
        DemoText1 d1 = new DemoText1("张三");
        DemoText1 d2 = new DemoText1("李四");
        d2.start();
        d1.run();
        */



        //创建Runnable子类对象，注意他不是线程对象
        DemoText2  d1= new DemoText2();
        //创建Thread类的对象，将Runnable接口的子类对象作为参数传递给Thread类的构造函数
        Thread t1 =new Thread(d1);
        Thread t2 = new Thread(d1);
        Thread t3 =new Thread(d1);
        Thread t4 =new Thread(d1);
        //将线程启动
        t1.start();
        t2.start();
        t3.start();
        t4.start();
/**       //主线程执行到这里，知道t1要加入释放执行权
        //主线程跑到冻结状态，知道t1线程执行完后，恢复
        //执行权有主线程跟t2线程一起抢夺
        try{t1.join();} catch (InterruptedException e) { }
        t2.start();
        for (int i = 0; i < 200; i++) {
            System.out.println("main---------------------"+i);
        }
        System.out.println("over");*/
    }
}
